using System;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;

using FormsGenerator.Xml;
using FormsGenerator.FormsGeneratorException;
using FormsGenerator.Controls;


namespace FormsGenerator
{
    /// <summary>
    /// Summary description for EditForm.
    /// </summary>
    public partial class EditForm : System.Web.UI.Page
    {

        protected XmlDocument formXmlDoc;

        protected FormsGenerator.Controls.TopBanner theTopBanner;

        protected int pageNumber = 1;
        protected Hashtable deleteButtons;

        protected void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here
            /*
            XmlDocument FormElements = (XmlDocument)Application["FormElements"];
            LabelDebug.Text = Server.HtmlEncode(FormElements.InnerXml);
            */
            //Important that ViewState comes before Request["id"], while ViewState is the master.
            //If not, the Render method might be called twice when handling an event.
            if (ViewState["Guid"] != null && !((string)ViewState["Guid"]).Equals(""))
            {
                try
                {
                    formXmlDoc = XmlHandler.GetForm((string)ViewState["Guid"]);
                    ViewState["Guid"] = (string)ViewState["Guid"];
                }
                catch (PermissionDeniedException ex)
                {
                    Session["ErrorMessage"] = ex.Message;
                    //Use Server.Transfer to support Reverse proxy. Do not use Response.Redirect!
                    Server.Transfer("Default.aspx");
                }
                catch (Exception ex)
                {
                    LabelErrorMessage.Text = ex.Message;
                    LabelErrorMessage.Visible = true;
                }
            }
            //Used for other pages calling this page, and not for round-trips (where ViewState is used)
            else if (Request["id"] != null)
            {
                try
                {
                    formXmlDoc = XmlHandler.GetForm(Request["id"]);
                    ViewState["Guid"] = Request["id"];
                }
                catch (PermissionDeniedException ex)
                {
                    Session["ErrorMessage"] = ex.Message;
                    //Use Server.Transfer to support Reverse proxy. Do not use Response.Redirect!
                    Server.Transfer("Default.aspx");
                }
                catch (Exception ex)
                {
                    LabelErrorMessage.Text = ex.Message;
                    LabelErrorMessage.Visible = true;
                }
            }

            if (!IsPostBack && Request["page"] != null)
            {
                pageNumber = int.Parse(Request["page"]);
                Session[ViewState["Guid"] + "_page"] = pageNumber;
                ViewState["Page"] = pageNumber;
            }
            else if (ViewState["Page"] != null)
            {
                pageNumber = (int)ViewState["Page"];
                Session[ViewState["Guid"] + "_page"] = pageNumber;
            }
            else if (Session[ViewState["Guid"] + "_page"] != null)
            {
                pageNumber = (int)Session[ViewState["Guid"] + "_page"];
                ViewState["Page"] = pageNumber;
            }

            if (formXmlDoc != null)
            {
                //A dirty way of adding delete buttons to the rows in the table
                //Must be done in Page_Load to wire the events to the buttons!
                XmlNodeList tableRows = formXmlDoc.SelectNodes("/form/page[" + pageNumber + "]/row");
                deleteButtons = new Hashtable();
                // + 2 is because we need an additional button if a new row is inserted!
                for (int i = 1; i < tableRows.Count + 2; i++)
                {
                    LinkButton deleteRowButton = new LinkButton();
                    deleteRowButton.ID = "deleteRow_" + i;
                    deleteRowButton.Text += "delete";
                    deleteRowButton.CssClass = "DeleteRow";
                    ShowHelpBox.AddOnmousePopupHelp("Click to delete row", deleteRowButton);
                    deleteRowButton.Attributes["onClick"] = "return confirm(\"Are you sure you want to delete the row?\")";
                    deleteRowButton.CommandName = "deleteRow";
                    deleteRowButton.CommandArgument = "" + i;
                    deleteRowButton.Command += new CommandEventHandler(this.deleteRow_Click);
                    //Need this dummy to wire the events.... weird thing!?!
                    PlaceHolderDeleteButtons.Controls.Add(deleteRowButton);
                    deleteButtons.Add(i, deleteRowButton);
                }
            }

            if (!IsPostBack)
            {
                try
                {
                    InputButtonClose.DataBind();
                    ButtonSaveAndReturn.DataBind();
                    Render();
                }
                catch (Exception ex)
                {
                    LabelErrorMessage.Text = ex.Message;
                    LabelErrorMessage.Visible = true;
                }
            }
            else
            {
                LabelDebug.Text += "Postback!!!, ID " + sender + ", args: " + Request.Form["selectedItem"];
            }
            deleteItem.Attributes["onClick"] = "return deleteItem()";
            //this.deleteItem.Click += new System.EventHandler(this.deleteItem_Click);
        }

        private void DrawFormDesignTable(XmlDocument theForm, Hashtable validationErrors)
        {
            int numOfCols;
            string nodevalue = "";
            nodevalue = theForm.SelectSingleNode("/form/page[" + pageNumber + "]/numofcols").InnerText.Trim();
            if (!nodevalue.Equals(""))
            {
                ButtonInsert.Enabled = true;
                numOfCols = int.Parse(nodevalue);
                //Creating header row			
                TableCell newHeaderCell = new TableCell();
                newHeaderCell.Text = "Row";
                newHeaderCell.CssClass = "FormDesignerTableHeader";
                TableFormDesignHeader.Cells.Add(newHeaderCell);
                for (int i = 1; i <= numOfCols; i++)
                {
                    newHeaderCell = new TableCell();
                    newHeaderCell.Text = "Column " + (i);
                    newHeaderCell.CssClass = "FormDesignerTableHeader";
                    TableFormDesignHeader.Cells.Add(newHeaderCell);
                }
                //Adding additional column for action cells
                newHeaderCell = new TableCell();
                TableFormDesignHeader.Cells.Add(newHeaderCell);

                XmlNode pageNode = theForm.SelectSingleNode("/form/page[" + pageNumber + "]");
                //LabelDebug.Text += "<br /><br />PageNode: " + pageNode.OuterXml + "<br />" ;

                XmlNodeList rows = pageNode.SelectNodes(".//row");
                LabelDebug.Text += "<br /><br />Count: " + rows.Count + "<br />";
                for (int y = 1; y <= rows.Count; y++)
                {
                    XmlNode row = rows[y - 1];
                    TableRow newRow = new TableRow();
                    TableCell newRowCell = new TableCell();
                    Label labelRowNumber = new Label();
                    labelRowNumber.Text = "" + y;
                    labelRowNumber.CssClass = "FormDesignerTableRowNr";
                    newRowCell.Controls.Add(labelRowNumber);
                    newRow.Cells.Add(newRowCell);
                    int x = 1; //Used for positioning
                    foreach (XmlElement cell in row.ChildNodes)
                    {
                        //Do not render cells beyond number of cols...
                        if (x > numOfCols)
                        {
                            break;
                        }
                        newRowCell = new TableCell();
                        string alignment = cell.GetAttribute("align");
                        if (alignment.Length > 0)
                        {
                            newRowCell.Attributes.Add("align", alignment);
                        }
                        string colSpan = cell.GetAttribute("colspan");
                        int columnSpan = 1;
                        if (colSpan.Length > 0)
                        {
                            try
                            {
                                columnSpan = int.Parse(colSpan);
                                newRowCell.ColumnSpan = columnSpan;
                                x += (columnSpan - 1);
                            }
                            catch (Exception e)
                            {
                                throw new ApplicationException("Colspan, " + e.Message);
                            }
                        }
                        //If not an empty cell
                        if (cell.HasChildNodes)
                        {
                            //Items in cell
                            int itemCounter = 1;
                            //Adding dropzone for drag'n'drop
                            newRowCell.Controls.Add(GetDropZoneControl("span", y + "_" + (x - (columnSpan - 1)) + "_" + itemCounter));
                            foreach (XmlElement item in cell.ChildNodes)
                            {
                                HtmlGenericControl containerHTMLControl = null;
                                containerHTMLControl = GetHTMLContainer(item, y + "_" + (x - (columnSpan - 1)) + "_" + itemCounter, validationErrors);
                                newRowCell.Controls.Add(containerHTMLControl);
                                newRowCell.CssClass = "FormDesignerTableCell";
                                newRowCell.Controls.Add(GetDropZoneControl("span", y + "_" + (x - (columnSpan - 1)) + "_" + (itemCounter + 1)));
                                //newRowCell.Wrap = false;
                                newRow.Cells.Add(newRowCell);
                                itemCounter++;
                            }
                        }
                        else
                        {
                            HtmlGenericControl containerHTMLControl = GetHTMLContainer(null, y + "_" + (x - (columnSpan - 1)) + "_1", validationErrors);
                            newRowCell.Controls.Add(GetDropZoneControl("span", y + "_" + (x - (columnSpan - 1)) + "_1"));
                            newRowCell.Controls.Add(containerHTMLControl);
                            newRowCell.CssClass = "FormDesignerTableCell";
                            newRow.Cells.Add(newRowCell);
                        }
                        x++;
                    }
                    //Adding additional empty cells
                    for (; x <= numOfCols; x++)
                    {
                        newRowCell = new TableCell();
                        HtmlGenericControl containerHTMLControl = GetHTMLContainer(null, y + "_" + x + "_1", validationErrors);
                        newRowCell.Controls.Add(GetDropZoneControl("span", y + "_" + x + "_1"));
                        newRowCell.Controls.Add(containerHTMLControl);
                        newRowCell.CssClass = "FormDesignerTableCell";
                        newRow.Cells.Add(newRowCell);
                    }
                    //Adding rowcell at end with actionbuttons
                    // Adding delete button
                    newRowCell = new TableCell();

                    //Not able to use LinkButton because eventhandlers cannot be added
                    //after Page_Load
                    /*HyperLink deleteRowButton = new HyperLink();
                    newRowCell.Controls.Add(deleteRowButton);
                    deleteRowButton.ID = "deleteRow_" + y;
                    deleteRowButton.Text += "delete";
                    deleteRowButton.CssClass = "DeleteRow";					
                    ShowHelpBox.AddOnmousePopupHelp("Click to delete row", deleteRowButton);
                    */
                    //deleteRowButton.NavigateUrl = "javascript: deleteRow('EditForm.aspx?id=" + ViewState["Guid"] + "&page=" + pageNumber + "&deleterow=" + y + "')";
                    //deleteRowButton.NavigateUrl = "javascript: deleteRow('deleteRow_" + y + "')";
                    LinkButton deleteRowButton = (LinkButton)deleteButtons[y];
                    newRowCell.Controls.Add(deleteRowButton);
                    newRow.Cells.Add(newRowCell);

                    //Adding row to table
                    TableFormDesign.Rows.Add(newRow);
                    DropDownListInsertRow.Items.Add(new ListItem("Before row " + (y), "" + (y)));
                }
            }
        }

        private void Render()
        {
            //Check to show instructions panel for this page!
            if (Session["ShowHelp"] != null && !(bool)Session["ShowHelp"])
            {
                PanelInstructions.Visible = false;
            }
            else
            {
                PanelInstructions.Visible = true;
            }

            if (formXmlDoc != null)
            {
                PanelNumberOfPages.Visible = false;
                PanelInstructions2.Visible = true;
                PanelInstructions1.Visible = false;
                string nodevalue = "";
                string strGuid = "";
                //Setting property fields								
                if (formXmlDoc.SelectSingleNode("/form/page[" + pageNumber + "]") == null)
                {
                    throw new ApplicationException("Page does not exist.");
                }

                //Clearing the DropDownlists
                DropDownListAddPage.Items.Clear();
                DropDownListAddPage.Items.Add(new ListItem("At end", "-1"));

                DropDownListInsertRow.Items.Clear();
                DropDownListInsertRow.Items.Add(new ListItem("At end", "-1"));

                //Filling in Paging
                XmlNodeList pageNodes = formXmlDoc.SelectNodes("/form/page");


                if (pageNodes.Count > 1)
                {
                    //Creating the left arrow
                    if (pageNumber > 1)
                    {
                        LabelPaging.Text = "<a href=\"EditForm.aspx?id=" + ViewState["Guid"] + "&page=" + (pageNumber - 1) + "\">&lt;&lt;</a>&nbsp;";
                    }

                    //Creating the numbers with links
                    for (int i = 1; i <= pageNodes.Count; i++)
                    {
                        if (i == pageNumber)
                        {
                            LabelPaging.Text += i + "&nbsp;";
                        }
                        else
                        {
                            LabelPaging.Text += "<a href=\"EditForm.aspx?id=" + ViewState["Guid"] + "&page=" + i + "\">" + i + "</a>&nbsp;";
                        }
                        //Adding pages to DropDownlist
                        ListItem newPageItem = new ListItem("Before page " + i, "" + i);
                        DropDownListAddPage.Items.Add(newPageItem);
                    }

                    //Creating the right arrow
                    if (pageNumber < pageNodes.Count)
                    {
                        LabelPaging.Text += "<a href=\"EditForm.aspx?id=" + ViewState["Guid"] + "&page=" + (pageNumber + 1) + "\">&gt;&gt;</a>&nbsp;";
                    }
                    LinkButtonDeletePage.Attributes["onClick"] = "return confirm(\"Are you sure you want to delete this page?\")";
                    LinkButtonDeletePage.Visible = true;
                }
                else
                {
                    LinkButtonDeletePage.Visible = false;
                }

                //Filling in controls values
                nodevalue = formXmlDoc.SelectSingleNode("/form/page[" + pageNumber + "]/numofcols").InnerText.Trim();
                TextBoxNumOfCols.Text = "" + nodevalue;
                nodevalue = formXmlDoc.SelectSingleNode("/form/properties/guid").InnerText.Trim();
                LabelID.Text = "" + nodevalue;
                strGuid = "" + nodevalue;
                nodevalue = formXmlDoc.SelectSingleNode("/form/properties/name").InnerText.Trim();
                TextBoxName.Text = "" + nodevalue;

                // Drawing the form
                try
                {
                    //Validate Form
                    Hashtable validationErrors = ValidateForm(formXmlDoc);
                    if (validationErrors.Count > 0)
                    {
                        LabelErrorMessage.Text += "Warning! The form is not valid.<ul>";
                        foreach (string errorMessage in validationErrors.Values)
                        {
                            LabelErrorMessage.Text += "<li>" + errorMessage + "</li>";
                        }
                        LabelErrorMessage.Text += "</ul>";
                        LabelErrorMessage.Visible = true;
                    }

                    DrawFormDesignTable(formXmlDoc, validationErrors);
                    LabelDebug.Text += "<br />" + Server.HtmlEncode(formXmlDoc.InnerXml);

                    bool disableInputFields = false;
                    XmlElement lockedByElement = (XmlElement)formXmlDoc.SelectSingleNode("/form/properties/lockedby");
                    if (lockedByElement != null)
                    {
                        string lockedBy = lockedByElement.InnerText.Trim();
                        Trace.Write("Logon", HttpContext.Current.User.Identity.Name.ToLower() + "=" + lockedBy.ToLower());
                        if (!HttpContext.Current.User.Identity.Name.ToLower().Equals(lockedBy.ToLower()))
                        {
                            disableInputFields = true;
                        }
                    }

                    //Handling input controls
                    ButtonViewSource.Attributes["onClick"] = "window.open('viewSource.aspx?id=" + strGuid + "', 'ViewSource', 'toolbar=no,titlebar=no,resizable=yes');";
                    ButtonPreview.Attributes["onClick"] = "window.open('Preview.aspx?id=" + strGuid + "', 'Preview', 'toolbar=no,titlebar=no,resizable=yes,scrollbars=yes');";
                    if (disableInputFields)
                    {
                        ButtonPreview.Disabled = false;
                        ButtonViewSource.Disabled = false;
                        ButtonSaveAndReturn.Enabled = true;
                        PanelTheForm.Visible = true;
                        PanelPages.Visible = true;
                        LabelNumOfPages.Visible = false;
                        TextBoxNumOfPages.Visible = false;
                        ButtonAddPage.Enabled = false;
                        ButtonInsert.Enabled = false;
                        ButtonAddPage.Enabled = false;
                        ButtonFormPropertiesUpdate.Enabled = false;
                        LinkButtonDeletePage.Visible = false;
                        LabelErrorMessage.Text += "The form is not locked by you, and you can not make any changes to the form!<br />" + LabelErrorMessage.Text;
                        LabelErrorMessage.Visible = true;
                    }
                    else
                    {
                        ButtonPreview.Disabled = false;
                        ButtonViewSource.Disabled = false;
                        ButtonSaveAndReturn.Enabled = true;
                        PanelTheForm.Visible = true;
                        PanelPages.Visible = true;
                        LabelNumOfPages.Visible = false;
                        TextBoxNumOfPages.Visible = false;
                        ButtonAddPage.Enabled = true;
                    }

                }
                catch (Exception ex)
                {
                    LabelErrorMessage.Text = "Error: " + ex + "<br />Please click the View Source Button and correct the error!";
                    LabelErrorMessage.Visible = true;
                    ButtonPreview.Disabled = false;
                    ButtonPreview.Attributes["onClick"] = "window.open('Preview.aspx?id=" + strGuid + "', 'Preview', 'toolbar=no,titlebar=no,resizable=yes');";
                    ButtonViewSource.Disabled = false;
                    ButtonViewSource.Attributes["onClick"] = "window.open('viewSource.aspx?id=" + strGuid + "', 'ViewSource', 'toolbar=no,titlebar=no,resizable=yes');";
                    ButtonFormPropertiesUpdate.Enabled = false;
                    ButtonSaveAndReturn.Enabled = false;
                    PanelTheForm.Visible = false;
                    PanelPages.Visible = false;
                    LabelNumOfPages.Visible = false;
                    TextBoxNumOfPages.Visible = false;
                    ButtonAddPage.Enabled = false;
                }
            }
            else
            {
                PanelInstructions1.Visible = true;
                PanelInstructions2.Visible = false;
                PanelNumberOfPages.Visible = true;
            }
            //check if paging is enabled:
            string allowPagingString = ConfigurationManager.AppSettings["AllowPaging"];
            bool allowPaging = true;
            if (!allowPagingString.Equals(string.Empty))
            {
                allowPaging = bool.Parse(allowPagingString);
            }
            PanelAddPage.Visible = allowPaging;

            //hide the rest of the page-specific elements:
            LabelNumOfPages.Visible = allowPaging;
            TextBoxNumOfPages.Visible = allowPaging;
            RangeValidator2.Visible = allowPaging;
            TextBoxNumOfPages.Visible = allowPaging;

            LabelDebug.Text += "ViewState:" + ViewState["Guid"] + "<br />";


        }

        private Hashtable ValidateForm(XmlDocument formXmlDoc)
        {
            Hashtable errorMessages = new Hashtable();
            Hashtable existingHtmlElementNames = new Hashtable();
            XmlNodeList pages = formXmlDoc.SelectNodes("/form/page");

            for (int pageNumber = 1; pageNumber <= pages.Count; pageNumber++)
            {
                XmlElement currentPage = (XmlElement)pages[pageNumber - 1];
                XmlNodeList htmlElementNodes = currentPage.SelectNodes(".//element/*[@name !='']");
                XmlElement fieldNode = null;
                foreach (XmlNode htmlElementNode in htmlElementNodes)
                {
                    if (htmlElementNode.Name != "element" && htmlElementNode.Name != "validation")
                    {
                        fieldNode = htmlElementNode as XmlElement;
                        string nameAttribute = fieldNode.GetAttribute("name");
                        string typeAttribute = fieldNode.GetAttribute("type");
                        if (existingHtmlElementNames.ContainsKey(nameAttribute.ToLower()))
                        {
                            int existingPageNumber = (int)existingHtmlElementNames[nameAttribute.ToLower()];
                            if (!string.IsNullOrEmpty(typeAttribute) && typeAttribute.ToLower() == "radio" )
                            {
                                if (existingPageNumber != pageNumber)
                                {
                                    errorMessages[nameAttribute] = "There are duplicate radiobuttons named \"" + nameAttribute + "\" on page " + existingPageNumber + " and page " + pageNumber + ". Radiobuttons with identical names can only exist on same page!";
                                }
                            }
                            else
                            {
                                string errorMessage = "There are duplicate names in the form! {0}. Please change the name for one of the items!<br />";
                                if (existingPageNumber == pageNumber)
                                {
                                    errorMessages[nameAttribute] = errorMessages[nameAttribute] + string.Format(errorMessage, "\"" + nameAttribute + "\" exists twice on page " + pageNumber);
                                }
                                else
                                {
                                    errorMessages[nameAttribute] = errorMessages[nameAttribute] + string.Format(errorMessage, "\"" + nameAttribute + "\" exists on page " + existingPageNumber + " and page " + pageNumber);
                                }
                            }
                        }
                        else
                        {
                            existingHtmlElementNames.Add(nameAttribute.ToLower(), pageNumber);
                        }
                    }
                }
            }
            return errorMessages;

        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {

        }
        #endregion

        protected void ButtonFormPropertiesUpdate_Click(object sender, System.EventArgs e)
        {
            UpdateForm();
        }

        private void UpdateForm()
        {
            if (Page.IsValid)
            {
                XmlNode theNode;
                string formName = TextBoxName.Text.Trim();
                // Create new form
                if (formXmlDoc == null)
                {
                    int numOfPages = 1;
                    if (TextBoxNumOfPages.Text.Trim().Length > 0)
                    {
                        numOfPages = int.Parse(TextBoxNumOfPages.Text);
                    }
                    formXmlDoc = XmlHandler.CreateForm(formName, numOfPages, HttpContext.Current.User.Identity.Name);
                    theNode = formXmlDoc.SelectSingleNode("/form/properties/guid");
                    ViewState["Guid"] = theNode.InnerText;
                    LabelDebug.Text += "formXmlDoc = null!";
                }
                else
                {
                    //Setting nodevalues fields				
                    int numOfCols = int.Parse(TextBoxNumOfCols.Text);
                    theNode = formXmlDoc.SelectSingleNode("/form/page[" + pageNumber + "]/numofcols");
                    theNode.InnerText = "" + numOfCols;
                    theNode = formXmlDoc.SelectSingleNode("/form/properties/name");
                    theNode.InnerText = formName;
                    try
                    {
                        XmlHandler.SaveForm((string)ViewState["Guid"], formXmlDoc, HttpContext.Current.User.Identity.Name);
                    }
                    catch (Exception pdex)
                    {
                        LabelErrorMessage.Text = pdex.Message;
                        LabelErrorMessage.Visible = true;
                    }
                }
                //Render is called in OnBubbleEvent
            }
        }

        protected void ButtonSaveAndReturn_Click(object sender, System.EventArgs e)
        {
            //Use Server.Transfer to support Reverse proxy. Do not use Response.Redirect!
            Server.Transfer("Default.aspx");
        }

        protected void ButtonAddPage_Click(object sender, System.EventArgs e)
        {
            //Do not have to validate the page, since we're only adding a node
            // to the Xml
            int offset = int.Parse(DropDownListAddPage.SelectedItem.Value);
            //LabelDebug.Text += "<br /><br />You selected index: " + offset + "<br />";

            try
            {
                if (formXmlDoc != null)
                {
                    XmlHandler.AddPage((string)ViewState["Guid"], offset, formXmlDoc, HttpContext.Current.User.Identity.Name);
                }
                else
                {
                    throw new ApplicationException("Form is not available! Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }
            //Render is called in OnBubbleEvent
        }

        protected void ButtonInsert_Click(object sender, System.EventArgs e)
        {
            //Do not have to validate the page, since we're only adding a node
            // to the Xml
            int offset = int.Parse(DropDownListInsertRow.SelectedItem.Value);
            LabelDebug.Text += "<br /><br />You selected index: " + offset + "<br />";

            try
            {
                if (formXmlDoc != null)
                {
                    XmlHandler.AddRow((string)ViewState["Guid"], offset, pageNumber, formXmlDoc, HttpContext.Current.User.Identity.Name);
                }
                else
                {
                    throw new ApplicationException("Form is not available!Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }

            //Render is called in OnBubbleEvent			
        }

        private HtmlGenericControl GetHTMLContainer(XmlElement item, string id, Hashtable formValidaionErrors)
        {
            HtmlGenericControl spanHTMLControl = new HtmlGenericControl("span");
            string strOnMouseText = "";
            string menuToShow = "emptyItemMenu";
            spanHTMLControl.Attributes["class"] = "ContainerHidden";
            if (item != null)
            {
                //Render the element
                XmlElement element = (XmlElement)item.SelectSingleNode("./element").FirstChild;
                string elementName = element.Name;
                HtmlGenericControl htmlControl = new HtmlGenericControl(elementName);

                string strHTML = "";
                //Handling labels. HTML content is stored in CData sections
                if (element.FirstChild != null && element.FirstChild.NodeType == XmlNodeType.CDATA)
                {
                    strHTML = ((XmlCDataSection)element.FirstChild).Data;
                }
                else
                {
                    strHTML = element.InnerXml;
                }
                if (strHTML.Length > 0)
                {
                    htmlControl.InnerHtml = strHTML;
                }

                //Get the attributes for the element
                XmlAttributeCollection elementAttributes = element.Attributes;
                foreach (XmlAttribute elementAttribute in elementAttributes)
                {
                    string strAttributeName = elementAttribute.Name;
                    string strAttributeValue = elementAttribute.Value;
                    if (!strAttributeName.Equals(""))
                    {
                        htmlControl.Attributes.Add(strAttributeName, strAttributeValue);
                    }
                }

                //Create the ShowHelp string
                ArrayList removeAttributes = new ArrayList();
                XmlElement elementNode = element.ParentNode as XmlElement;
                string isDynamic = elementNode.GetAttribute("isdynamic");
                string appendIsDynamic = "";
                if (!string.IsNullOrEmpty(isDynamic) && isDynamic == "true")
                {
                    appendIsDynamic = " - dynamic";
                }
                strOnMouseText = elementNode.GetAttribute("name") + " (" + htmlControl.TagName + appendIsDynamic + ")"; // @ " + id;
                if (htmlControl.Attributes.Count > 0)
                {
                    strOnMouseText += "<hr class=\"helpHr\">";
                    foreach (string strKey in htmlControl.Attributes.Keys)
                    {
                        if (!(strKey.ToLower().Equals("innerhtml") || strKey.ToLower().Equals("innertext")))
                        {
                            strOnMouseText += "<b>" + strKey + "</b>=" + htmlControl.Attributes[strKey] + "<br />";
                        }
                        //Adding attributes to be removed. They cannot be removed her, 
                        //because the foreach loop will fail					
                        if (strKey.ToLower().StartsWith("on"))
                        {
                            removeAttributes.Add(strKey);
                        }
                    }
                    //removing eventattributes in designer
                    for (int i = 0; i < removeAttributes.Count; i++)
                    {
                        string strAttribute = (string)removeAttributes[i];
                        htmlControl.Attributes.Remove(strAttribute);
                    }
                }

                //Adding validation information to ShowHelp
                XmlNodeList validations = item.SelectNodes("./validations/validation");
                if (validations.Count > 0)
                {
                    HtmlGenericControl validationMark = new HtmlGenericControl("span");
                    validationMark.Attributes["class"] = "validationMark";
                    validationMark.InnerHtml = "*";
                    spanHTMLControl.Controls.Add(validationMark);
                    strOnMouseText += "<br />Validations:<br />";
                    strOnMouseText += "<hr class=\"helpHr\">";
                    foreach (XmlElement validation in validations)
                    {
                        string validationName = validation.GetAttribute("name");
                        string validationId = validation.GetAttribute("id");
                        string validationErrorMessage = validation.GetAttribute("errormessage");
                        if (validationId == null || validationId.Equals(""))
                        {
                            strOnMouseText += "Customvalidation<br />";
                        }
                        else if (validationName == null || validationName.Equals(""))
                        {
                            strOnMouseText += "[NoName]<br />";
                        }
                        else
                        {
                            strOnMouseText += validationName + "<br />";
                        }

                        if (validationErrorMessage != null)
                        {
                            if (validationErrorMessage != string.Empty)
                            {
                                strOnMouseText += "<div class=\"validationErrorMessage\">&quot;" + validationErrorMessage + "&quot;</div><br />";
                            }
                            else
                            {
                                strOnMouseText += "<div class=\"validationErrorMessage\">[no errormessage]</div><br />";
                            }
                        }
                    }
                }

                //If the form is invalid, mark the invalid items
                string nameAttribute = htmlControl.Attributes["name"];
                if (!string.IsNullOrEmpty(nameAttribute) && formValidaionErrors.ContainsKey(nameAttribute))
                {
                    spanHTMLControl.Style.Add("background", "red");
                    htmlControl.Style.Add("background", "red");
                }

                spanHTMLControl.Controls.Add(htmlControl);
                menuToShow = "existingItemMenu";

                //Adding drag'n'drop code
                spanHTMLControl.Attributes["onmousedown"] = "mouseClick(this)";
                spanHTMLControl.Attributes["ondragstart"] = "startDrag()";
                spanHTMLControl.Attributes["ondragend"] = "endDrag()";
                spanHTMLControl.Attributes["onmouseover"] += "mouseEnter(this);";
                spanHTMLControl.Attributes["onmouseout"] += "mouseOut(this);";

                //Hidden controls
                if (htmlControl.Attributes["type"] == "hidden")
                {
                    spanHTMLControl.InnerText = "[Hidden]";
                }


                //If the label is empty, use the wide style to fill the cell
                if (htmlControl.TagName == "span" && (htmlControl).InnerHtml.Trim().Length == 0)
                {
                    (htmlControl).InnerHtml = "&nbsp;";
                    spanHTMLControl.Attributes["class"] = "ContainerEmpty";
                }

                //Add the position style attribute
                htmlControl.Attributes["hideSelect"] = "true";
                htmlControl.Style.Add("position", "relative");
            }
            else
            {
                spanHTMLControl.Attributes["class"] = "ContainerEmpty";
            }
            string showContainerJS = "showContainer(this, '" + id + "', '" + strOnMouseText + "', '" + menuToShow + "');";
            spanHTMLControl.Attributes["onmouseover"] += showContainerJS;
            spanHTMLControl.Attributes["onmouseout"] += "hideContainer(this);";
            spanHTMLControl.Attributes["onmousemove"] += showContainerJS;
            return spanHTMLControl;
        }

        private HtmlGenericControl GetDropZoneControl(string tagname, string position)
        {
            HtmlGenericControl spanHTMLControl = new HtmlGenericControl(tagname);
            spanHTMLControl.Attributes["class"] = "Dropzone";
            spanHTMLControl.ID = "dz_" + position;
            spanHTMLControl.Attributes["name"] = "dropzone"; //used for scripting
            spanHTMLControl.Attributes["ondrop"] = "drop(this)";
            spanHTMLControl.Attributes["ondragover"] = "overDrag()";
            spanHTMLControl.Attributes["ondragenter"] = "enterDrag(this)";
            spanHTMLControl.Attributes["ondragleave"] = "leaveDrag(this)";
            return spanHTMLControl;
        }

        protected override bool OnBubbleEvent(object sender, EventArgs e)
        {
            try
            {
                Render();
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }
            return true;
        }

        protected void deleteItem_Click(object sender, System.EventArgs e)
        {

            try
            {
                if (formXmlDoc != null)
                {
                    XmlHandler.DeleteItem(formXmlDoc, pageNumber, Request.Form["selectedItem"], (string)ViewState["Guid"], HttpContext.Current.User.Identity.Name);
                }
                else
                {
                    throw new ApplicationException("Form is not available! Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }

        }

        private void deleteRow_Click(object sender, CommandEventArgs e)
        {
            try
            {
                if (formXmlDoc != null)
                {
                    LabelDebug.Text += "Deleting row!" + e.CommandArgument;
                    XmlHandler.DeleteRow((string)ViewState["Guid"], int.Parse((string)e.CommandArgument), pageNumber, formXmlDoc, HttpContext.Current.User.Identity.Name);
                }
                else
                {
                    throw new ApplicationException("Form is not available! Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }
        }

        protected void LinkButtonDeletePage_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (formXmlDoc != null)
                {
                    XmlHandler.DeletePage((string)ViewState["Guid"], pageNumber, formXmlDoc, HttpContext.Current.User.Identity.Name);
                    pageNumber--;
                    if (pageNumber < 1)
                    {
                        pageNumber = 1;
                    }
                    //Have to redirect to initialize controls again. Does not work to continue as usual because
                    //of eventhandlers for linkbuttons (delete row).
                    //Use Server.Transfer to support Reverse proxy. Do not use Response.Redirect!
                    Server.Transfer("EditForm.aspx?id=" + ViewState["Guid"] + "&page=" + pageNumber);
                }
                else
                {
                    throw new ApplicationException("Form is not available! Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }
        }

        protected void LinkButtonMoveItem_Click(object sender, System.EventArgs e)
        {
            LabelDebug.Text += "<br />moving item: " + Request.Form["selectedItem"] + " to position " + Request.Form["dropZoneID"];

            try
            {
                if (formXmlDoc != null)
                {
                    XmlHandler.moveItem(formXmlDoc, pageNumber, Request.Form["selectedItem"], Request.Form["dropZoneID"], (string)ViewState["Guid"], HttpContext.Current.User.Identity.Name);
                }
                else
                {
                    throw new ApplicationException("Form is not available! Please reload the form");
                }
            }
            catch (Exception ex)
            {
                LabelErrorMessage.Text = ex.Message;
                LabelErrorMessage.Visible = true;
            }
        }

        protected void ButtonUpdateColumns_Click(object sender, System.EventArgs e)
        {
            UpdateForm();
        }

        public bool ButtonSaveAndReturnVisible
        {
            get
            {
                if (ConfigurationManager.AppSettings["EnableReturnButtonEditForm"] != null)
                {
                    return bool.Parse(ConfigurationManager.AppSettings["EnableReturnButtonEditForm"]);
                }
                else
                {
                    return true;
                }
            }
        }

        public bool ButtonCloseVisible
        {
            get
            {
                if (ConfigurationManager.AppSettings["EnableCloseButtonEditForm"] != null)
                {
                    return bool.Parse(ConfigurationManager.AppSettings["EnableCloseButtonEditForm"]);
                }
                else
                {
                    return false;
                }
            }
        }
    }
}
